package library.net.retrofit;

import java.util.List;
import java.util.Map;

import io.reactivex.Flowable;
import io.reactivex.Observable;
import library.net.retrofit.response.RxBaseResponse;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.PartMap;
import retrofit2.http.QueryMap;
import retrofit2.http.Streaming;
import retrofit2.http.Url;

/**
 * @author Created by qiang.hou on 2017/12/9.
 * @version 1.0
 */
public interface IBaseApi {
    /**
     * GET
     *
     * @param url  url(action)
     * @param maps params
     * @return Observable
     */
    @GET
    <T> Observable<RxBaseResponse<T>> executeGet(@Url String url, @QueryMap Map<String, Object> maps);

    /**
     * post with form
     *
     * @param url  url(action)
     * @param maps params
     * @return Observable
     */
    @POST
    @FormUrlEncoded
    <T> Observable<RxBaseResponse<T>> executePost(@Url String url, @FieldMap Map<String, Object> maps);

    /**
     * post with Body(json)
     *
     * @param url    url(action)
     * @param object params as Object
     * @return Observable
     */
    @POST
    <T> Observable<RxBaseResponse<T>> executePost(@Url String url, @Body Object object);

    /**
     * post with RequestBody
     *
     * @param url  url(action)
     * @param Body params as RequestBody
     * @return Observable
     */
    @POST
    <T> Observable<RxBaseResponse<T>> executePost(@Url String url, @Body RequestBody Body);

    /**
     * download smaller file
     *
     * @param url download url(action)
     * @return Observable
     */
    @GET
    Observable<ResponseBody> downloadSmallFile(@Url String url);

    /**
     * download smaller file
     *
     * @param url download url(action)
     * @return Observable
     */
    @GET
    Call<ResponseBody> downloadSmallFile2(@Url String url);

    /**
     * download bigger file using Streaming
     *
     * @param url download url(action)
     * @return Observable
     */
    @Streaming
    @GET
    Observable<ResponseBody> downloadBigFile(@Url String url);

    /**
     * upload image
     *
     * @param url         url(action)
     * @param requestBody image
     * @return Observable
     */
    @Multipart
    @POST
    <T> Observable<RxBaseResponse<T>> upLoadImage(
            @Url String url,
            @Part("image\"; filename=\"image.jpg") RequestBody requestBody);

    /**
     * upload file
     *
     * @param url  url(action)
     * @param file file
     * @return Observable
     */
    @POST
    Flowable<ResponseBody> uploadFile(@Url String url, @Body RequestBody file);

    /**
     * upload image
     *
     * @param url  url(action)
     * @param file file
     * @return Observable
     */
    @Multipart
    @POST
    <T> Observable<RxBaseResponse<T>> uploadFileWithPart(@Url String url, @Part() MultipartBody.Part file);

    /**
     * upload files with map
     *
     * @param url  url(action)
     * @param maps files
     * @return Observable
     */
    @Multipart
    @POST
    <T> Observable<RxBaseResponse<T>> uploadFiles(@Url String url, @Body Map<String, RequestBody> maps);

    /**
     * upload files with list
     *
     * @param url  url(action)
     * @param list files
     * @return Observable
     */
    @Multipart
    @POST
    <T> Observable<RxBaseResponse<T>> uploadFileWithPartList(@Url String url, @Part List<MultipartBody.Part> list);

    /**
     * upload files with list
     *
     * @param url  url(action)
     * @param maps files
     * @return Observable
     */
    @Multipart
    @POST
    <T> Observable<RxBaseResponse<T>> uploadFileWithPartMap(@Url String url, @PartMap Map<String, MultipartBody.Part> maps);
}
